﻿using System;
using System.Collections.Generic;
using System.Text;
using NUnit.Framework;
using Net.Commons.Lang;

namespace Net.Commons.LangTest {
    [TestFixture]
    public class ToStringBuilderTest {
        [Test]
        public void String2String() {
            string s = "test";
            string actual = ToStringBuilder.ToString(s);
            string expected = "\"test\"";
            Assert.AreEqual(expected, actual);
        }
        [Test]
        public void Int2String() {
            string actual = ToStringBuilder.ToString(3);
            string expected = "3";
            Assert.AreEqual(expected, actual);
        }
        [Test]
        public void Long2String() {
            string actual = ToStringBuilder.ToString(1L);
            string expected = "1";
            Assert.AreEqual(expected, actual);
        }
        [Test]
        public void Decimal2String() {
            Decimal d = new Decimal(1.3f);
            string actual = ToStringBuilder.ToString(d);
            string expected = "1.3";
            Assert.AreEqual(expected, actual);
        }
        [Test]
        public void Single2String() {
            Single s = 2f;
            string actual = ToStringBuilder.ToString(s);
            string expected = "2";
            Assert.AreEqual(expected, actual);
        }
        [Test]
        public void Float2String() {
            float s = 2f;
            string actual = ToStringBuilder.ToString(s);
            string expected = "2";
            Assert.AreEqual(expected, actual);
        }
        [Test]
        public void DateTime2String() {
            DateTime s = DateTime.Now;
            string actual = ToStringBuilder.ToString(s);
            string expected = s.ToString();
            Assert.AreEqual(expected, actual);
        }
        [Test]
        public void DBNull2String() {
            string actual = ToStringBuilder.ToString(DBNull.Value);
            string expected = "<null>";
            Assert.AreEqual(expected, actual);
        }
        [Test]
        public void List2String() {
            IList<int> l = new List<int> { 1, 2, 3 };
            string actual = ToStringBuilder.ToString(l);
            string expected = "{1, 2, 3}";
            Assert.AreEqual(expected, actual);
        }
        [Test]
        public void Array2String() {
            int[] l = { 1, 2, 3 };
            string actual = ToStringBuilder.ToString(l);
            string expected = "[1, 2, 3]";
            Assert.AreEqual(expected, actual);
        }
        [Test]
        public void ListBean2String() {
            IList<TestBean> obj = new List<TestBean>();
            TestBean bean1 = new TestBean(1,null);
            obj.Add(bean1);
            IList<int> l = new List<int> { 1, 2, 3 };
            TestBean bean2 = new TestBean(2,l);
            obj.Add(bean2);
            string actual = ToStringBuilder.ToString(obj);
            string expected = "{TestBean<Id=1, List=<null>>, TestBean<Id=2, List={1, 2, 3}>}";
            Assert.AreEqual(expected, actual);
        }
        [Test]
        public void Dictionary2String() {
            IDictionary<int, string> obj = new Dictionary<int, string>();
            obj.Add(1, "val1");
            obj.Add(2, "val2");
            obj.Add(3, "val3");
            string actual = ToStringBuilder.ToString(obj);
            string expected = "{1=\"val1\", 2=\"val2\", 3=\"val3\"}";
            Assert.AreEqual(expected, actual);
        }
        [Test]
        public void DictionaryBean2String() {
            IDictionary<TestBean, string> obj = new Dictionary<TestBean, string>();
            IList<int> l = new List<int> { 1, 2, 3 };
            obj.Add(new TestBean(1, null), "val1");
            obj.Add(new TestBean(2,l), "val2");
            obj.Add(new TestBean(3,null), "val3");
            string actual = ToStringBuilder.ToString(obj);
            string expected = "{TestBean<Id=1, List=<null>>=\"val1\", TestBean<Id=2, List={1, 2, 3}>=\"val2\", TestBean<Id=3, List=<null>>=\"val3\"}";
            Assert.AreEqual(expected, actual);
        }
        [Test]
        public void Bean2String() {
            TestBean obj = new TestBean();
            obj.Id = 100;
            obj.List = new List<int> { 4, 5, 6 };
            string actual = ToStringBuilder.ToString(obj);
            string expected = "TestBean<Id=100, List={4, 5, 6}>";
            Assert.AreEqual(expected, actual);
        }

        [Test]
        public void BeanBean2String() {
            Test2Bean obj = new Test2Bean();
            obj.Name = "test";
            obj.Bean = new TestBean(1, new List<int> { 1, 2, 3 });
            string actual = ToStringBuilder.ToString(obj);
            string expected = "Test2Bean<Name=\"test\", Bean=TestBean<Id=1, List={1, 2, 3}>>";
            Assert.AreEqual(expected, actual);
        }

        [Test]
        public void Struct2String() {
            StructBean obj = new StructBean();
            obj.Id = 1;
            obj.Name = "test";
            string actual = ToStringBuilder.ToString(obj);
            string expected = "StructBean<Id=1, Name=\"test\">";
            Assert.AreEqual(expected, actual);
        }

        [Test]
        public void ToStringWithFormat() {
            int i = 0;
            long l = 1L;
            string s = "test";
            string actual = ToStringBuilder.ToStringFormat("i={0}, l={1}, s={2}", i, l, s);
            string expected = "i=0, l=1, s=\"test\"";
            Assert.AreEqual(expected, actual);
        }
    }

    public struct StructBean {
        private int id;
        public int Id {
            set { this.id = value; }
            get { return this.id; }
        }
        private string name;
        public string Name {
            set { this.name = value; }
            get { return this.name; }
        }
    }

    public class Test2Bean {
        private string name;
        public string Name {
            set { this.name = value; }
            get { return this.name; }
        }
        private TestBean bean;
        public TestBean Bean {
            set { this.bean = value; }
            get { return this.bean; }
        }
    }
    
    public class TestBean {
        public TestBean() { }
        public TestBean(int i, IList<int> l) {
            this.id = i;
            this.list = l;
        }
        private int id;
        public int Id {
            set { this.id = value; }
            get { return this.id; }
        }
        private IList<int> list;
        public IList<int> List {
            set { this.list = value; }
            get { return this.list; }
        }
    }
}
